package role

import (
	"context"
	"myapp/internal/dao"
	"myapp/internal/model"
	"myapp/internal/model/do"
	"myapp/internal/model/entity"
	"myapp/internal/service"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gtime"
)

type sRole struct{}

func init() {
	service.RegisterRole(New())
}

func New() *sRole {
	return &sRole{}
}

func (u *sRole) Create(ctx context.Context, in *model.RoleInput) (int64, error) {
	var err error
	if err = u.checkRoleName(ctx, in.Name, 0); err != nil {
		return 0, err
	}
	result, err := dao.Role.Ctx(ctx).Data(do.Role{
		Name:   in.Name,
		Pid:    in.Pid,
		Status: in.Status,
		Remark: in.Remark,
	}).Insert()

	if err != nil {
		return 0, err
	}
	id, err := result.LastInsertId()
	return id, err
}

// 检查用户名是否存在
func (u *sRole) GetOne(ctx context.Context, id int64) (*entity.Role, error) {
	role := &entity.Role{}
	err := dao.Role.Ctx(ctx).Where("id", id).Scan(role)
	if err != nil {
		return nil, err
	}

	return role, err
}

// 检查用户名是否存在
func (u *sRole) Update(ctx context.Context, in *model.RoleInput) error {
	id := in.Id
	if id < 1 {
		return gerror.New("id不能为空")
	}
	if err := u.checkRoleName(ctx, in.Name, id); err != nil {
		return err
	}

	var data g.Map = make(g.Map, 6)
	if in.Name != "" {
		data["name"] = in.Name
	}
	if in.Pid > 0 {
		data["pid"] = in.Pid
	}
	if in.Status == 0 || in.Status == 1 {
		data["status"] = in.Status
	}
	data["remark"] = in.Remark

	_, err := dao.Role.Ctx(ctx).Where("id", id).Data(data).Update()
	if err != nil {
		return err
	}
	return nil
}

// 检查用户名是否存在
func (u *sRole) Delete(ctx context.Context, id uint) (int64, error) {
	if id < 1 {
		return 0, gerror.New("id不能为空")
	}

	result, err := dao.Role.Ctx(ctx).Where("id", id).Delete()
	if err != nil {
		return 0, err
	}

	nums, err := result.RowsAffected()
	return nums, err

}

// 检查用户名是否存在, 并排除自己
func (u *sRole) checkRoleName(ctx context.Context, name string, id uint) error {
	if name == "" {
		return gerror.New("角色名不能为空")
	}
	m := dao.Role.Ctx(ctx).Where("name", name)
	if id > 0 {
		m = m.WhereNot("id", id)
	}
	count, err := m.Count()
	if err != nil {
		return err
	}
	if count > 0 {
		return gerror.New("用户已存在")
	}
	return nil
}

// 为一个用户赋予角色
func (u *sRole) AddMember(ctx context.Context, roleId, memberId uint) (int64, error) {
	var err error
	if err = u.checkRoleMember(ctx, roleId, memberId, 0); err != nil {
		return 0, err
	}
	result, err := dao.RoleUser.Ctx(ctx).Data(do.RoleUser{
		RoleId:     roleId,      // 角色id
		MemberId:   memberId,    // member.id
		CreateTime: gtime.Now(), // 创建时间
	}).Insert()

	if err != nil {
		return 0, err
	}
	id, err := result.LastInsertId()
	return id, err
}

// 检查用户名是否存在, 并排除自己
func (u *sRole) checkRoleMember(ctx context.Context, roleId, memberId, id uint) error {
	if roleId == 0 {
		return gerror.New("角色ID不能为空")
	}
	if memberId == 0 {
		return gerror.New("管理员ID不能为空")
	}
	m := dao.RoleUser.Ctx(ctx).Where("role_id=? and member_id =?", roleId, memberId)
	if id > 0 {
		m = m.WhereNot("id", id)
	}
	count, err := m.Count()
	if err != nil {
		return err
	}
	if count > 0 {
		return gerror.New("用户已存在")
	}
	return nil
}

// 获取一个用户的角色
func (u *sRole) GetRoleByMember(ctx context.Context, memberId uint) (*entity.Role, error) {
	roleUser := &entity.RoleUser{}
	err := dao.RoleUser.Ctx(ctx).Where("member_id", memberId).Limit(1).Scan(roleUser)
	if err != nil {
		return nil, err
	}

	role := &entity.Role{}
	err = dao.Role.Ctx(ctx).Where("id", roleUser.RoleId).Limit(1).Scan(role)
	if err != nil {
		return nil, err
	}
	return role, err
}

// 为一个用户赋予角色
func (u *sRole) RemoveMember(ctx context.Context, id uint) (int64, error) {
	var err error

	result, err := dao.RoleUser.Ctx(ctx).Where("id", id).Delete()

	if err != nil {
		return 0, err
	}
	nums, err := result.RowsAffected()
	return nums, err
}
